<template>
	<div>
		<el-dialog title="执行监听器" draggable width="900px" v-bind="$attrs">
			<div class="p-b-10">
				<el-button type="primary" @click="formData.executionListener.push({})" icon="Plus">新增</el-button>
				<!-- <el-button @click="listenerDialogVisible = true">内置监听器</el-button> -->
			</div>
			<el-form ref="formRef" :model="formData" label-width="0" inline-message>
				<my-table
					:data="formData.executionListener"
					:columns="[
						{
							label: '事件',
							prop: 'event'
						},
						{
							label: '类型',
							prop: 'type'
						},
						{
							label: '值',
							prop: 'className'
						},
						{
							label: '事件',
							prop: 'params'
						},
						{
							label: '操作',
							fixed: 'right',
							width: '70'
						}
					]"
					height="250"
				>
					<template #event="{ row, $index, prop }">
						<el-form-item
							:prop="`executionListener.${$index}.${prop}`"
							:rules="[{ required: true, message: '请选择', trigger: ['blur', 'change'] }]"
							v-if="$index >= 0"
						>
							<my-select
								v-model="row[prop]"
								:list="[
									{ label: 'start', value: 'start' },
									{ label: 'end', value: 'end' },
									{ label: 'take', value: 'take' }
								]"
								:fileType="{ label: 'label', value: 'value' }"
							/>
						</el-form-item>
					</template>
					<template #type="{ row, $index, prop }">
						<el-form-item
							:prop="`executionListener.${$index}.${prop}`"
							:rules="[{ required: true, message: '请选择', trigger: ['blur', 'change'] }]"
							v-if="$index >= 0"
						>
							<my-select
								v-model="row[prop]"
								:list="[
									{ label: '类', value: 'class' },
									{ label: '表达式', value: 'expression' },
									{ label: '委托表达式', value: 'delegateExpression' }
								]"
								:fileType="{ label: 'label', value: 'value' }"
							/>
						</el-form-item>
					</template>
					<template #className="{ row, $index, prop }">
						<el-form-item
							:prop="`executionListener.${$index}.${prop}`"
							:rules="[{ required: true, message: '请输入', trigger: ['blur', 'change'] }]"
							v-if="$index >= 0"
						>
							<my-input v-model="row[prop]" />
						</el-form-item>
					</template>
					<template #params="{ row, $index }">
						<el-badge :value="row?.params?.length || 0" type="primary">
							<el-button @click="configParam($index)">配置</el-button>
						</el-badge>
					</template>
					<template #default="{ $index }">
						<my-button-text @click="formData.executionListener.splice($index)">删除</my-button-text>
					</template>
				</my-table>
			</el-form>
			<template #footer>
				<el-button @click.prevent="$attrs['onUpdate:modelValue'](false)">取 消</el-button>
				<el-button type="primary" @click.prevent="() => closeDialog().then(() => $attrs['onUpdate:modelValue'](false))">确 定</el-button>
			</template>
			<!-- <listener-list :visible="listenerDialogVisible" @close="() => (listenerDialogVisible = false)" @submit="addListener" /> -->
		</el-dialog>
		<!-- <listenerParam v-if="showParamDialog" :value="formData.executionListener[nowIndex].params" @close="finishConfigParam" /> -->
	</div>
</template>

<script setup>
// import listenerParam from './listenerParam';
// import ListenerList from './listenerList';
import hooksPanel, { PanelProps } from '../../common/Panel';

const props = defineProps({
		...PanelProps
	}),
	{ formData, updateProperties } = hooksPanel(props);

onMounted(() => {
	formData.value.executionListener =
		props.element.businessObject.extensionElements?.values
			.filter((item) => item.$type === 'flowable:ExecutionListener')
			.map((item) => {
				let type;
				if ('class' in item) type = 'class';
				if ('expression' in item) type = 'expression';
				if ('delegateExpression' in item) type = 'delegateExpression';
				return {
					event: item.event,
					type: type,
					className: item[type],
					params:
						item.fields?.map((field) => {
							let fieldType;
							if ('stringValue' in field) fieldType = 'stringValue';
							if ('expression' in field) fieldType = 'expression';
							return {
								name: field.name,
								type: fieldType,
								value: field[fieldType]
							};
						}) ?? []
				};
			}) ?? [];
});
function updateElement() {
	if (formData.value.executionListener?.length) {
		let extensionElements = props.element.businessObject.get('extensionElements');
		if (!extensionElements) {
			extensionElements = props.modeler.get('moddle').create('bpmn:ExtensionElements');
		}
		// 清除旧值
		extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? [];
		formData.value.executionListener.forEach((item) => {
			const executionListener = props.modeler.get('moddle').create('flowable:ExecutionListener');
			executionListener['event'] = item.event;
			executionListener[item.type] = item.className;
			if (item?.params?.length) {
				item.params.forEach((field) => {
					const fieldElement = props.modeler.get('moddle').create('flowable:Field');
					fieldElement['name'] = field.name;
					fieldElement[field.type] = field.value;
					// 注意：flowable.json 中定义的string和expression类为小写，不然会和原生的String类冲突，此处为hack
					// const valueElement = props.modeler.get('moddle').create(`flowable:${field.type}`, { body: field.value })
					// fieldElement[field.type] = valueElement
					executionListener.get('fields').push(fieldElement);
				});
			}
			extensionElements.get('values').push(executionListener);
		});
		updateProperties({ extensionElements });
	} else {
		const extensionElements = props.element.businessObject[`extensionElements`];
		if (extensionElements) {
			extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? [];
		}
	}
}
const formRef = ref(null);
function closeDialog() {
	return formRef.value
		.validate()
		.then(() => {
			updateElement();
		})
		.catch((e) => console.error(e));
}

/********************************************************** */
const listenerDialogVisible = ref(false),
	showParamDialog = ref(false),
	nowIndex = ref(null);

function configParam(index) {
	nowIndex.value = index;
	const nowObj = formData.value.executionListener[index];
	if (!nowObj.params) nowObj.params = [];
	showParamDialog.value = true;
}
function finishConfigParam(param) {
	showParamDialog.value = false;
	formData.value.executionListener[nowIndex.value].params = param;
	nowIndex.value = null;
}

function addListener(data) {
	formData.value.executionListener = formData.value.executionListener.concat(data);
}
</script>
